<!--
 * @Date: 2022-04-12 13:42:33
 * @LastEditors: sailornpg
 * @LastEditTime: 2022-08-12 08:34:35
 * @FilePath: \weibovue\src\components\weiBoContentCard\index.vue
 * @Description: 微博内容显示
-->
<template>
  <div class="content" v-if="showContent">
    <div data-aos="fade-up">
      <div class="loadedContent" data-aos-anchor-placement="top-bottom">
        <div class="userinfo">
          <div class="useravatar" @click="goPersonal(BlogBaseInfo?.user?.id)">
            <img :src="BlogBaseInfo?.user?.avatar!" alt="" />
          </div>
          <div class="right">
            <div class="nickName">{{ BlogBaseInfo?.user?.nickName }}</div>
            <div class="createTime">
              {{
                typeof createTime(BlogBaseInfo?.createdAt) == "number"
                  ? createTime(BlogBaseInfo?.createdAt) + "小时前"
                  : createTime(BlogBaseInfo?.createdAt)
              }}
            </div>
          </div>
          <div v-if="store.state.isLogin" class="btnContainer">
            <div
              class="followBtnBox"
              v-if="BlogBaseInfo?.user?.id != userInfos.id"
            >
              <div
                class="btn"
                @click="followUser(BlogBaseInfo?.user?.id)"
                v-if="followBack"
              >
                <i class="iconfont icon-jia"></i>
                回关
              </div>
              <div
                class="unbtn"
                v-else-if="showUnFollow"
                @click="unFollowing(BlogBaseInfo?.user?.id)"
              >
                取消关注
              </div>
              <div
                class="btn"
                v-else
                @click="followUser(BlogBaseInfo?.user?.id)"
              >
                <i class="iconfont icon-jia"></i>
                关注
              </div>
            </div>
            <div
              v-if="BlogBaseInfo?.user?.id == userInfos.id || userInfos.id == 1"
              class="deleteBlogBox"
              @click="centerDialogVisible = true"
            >
              <i class="iconfont icon-shanchu1"></i>
            </div>
          </div>
        </div>
        <div class="weiboContent markdown-body" v-html="contentHTML"></div>
        <div class="weiboIMGList">
          <div
            class="imageItem"
            v-for="(item, index) in BlogBaseInfo?.imageUrl"
            :key="index"
            @click="previewImg(item)"
          >
            <img :src="item + '?param=300y300'" alt="" />
          </div>
        </div>

        <div class="tools">
          <div
            class="zan"
            :class="isLike ? 'like' : ''"
            @click="likeOrUnLikeBlog(BlogBaseInfo?.id)"
          >
            <i class="iconfont icon-dianzan1"></i> 点赞({{ likeCount }})
          </div>
          <div class="pinglun" @click="isShowComment = !isShowComment">
            <i class="iconfont icon-pinglun"></i>评论 ({{ commentCount }})
          </div>
        </div>
      </div>
    </div>
  </div>
  <div v-show="isShowComment">
    <topic
      :blogId="BlogBaseInfo?.id!"
      @getCommentCount="getCommentCount"
    ></topic>
  </div>
  <el-dialog
    v-model="centerDialogVisible"
    width="10%"
    top="40vh"
    center
    :show-close="false"
  >
    <span class="text">确定删除这篇博客吗?</span>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="centerDialogVisible = false">取消</el-button>
        <el-button type="warning" @click="deleteBlog(BlogBaseInfo?.id)"
          >确定</el-button
        >
      </span>
    </template>
  </el-dialog>
  <el-dialog v-model="dialogVisible">
    <img
      w-full
      :src="dialogImageUrl"
      alt="Preview Image"
      style="object-fit: cover"
    />
  </el-dialog>
</template>
<script lang="ts" setup>
import {
  computed,
  getCurrentInstance,
  onMounted,
  PropType,
  provide,
  ref,
  watch,
} from "vue";
import hljs from "highlight.js";
import "highlight.js/styles/atom-one-dark-reasonable.css";
import { WeiBoBaseType } from "./types";
import MarkdownIt from "markdown-it";
import mdMark from "markdown-it-mark";
import MarkdownItContainer from "markdown-it-container";
import "github-markdown-css";
import { createTime } from "../../utils/tools";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import { followListType, UserData } from "../createWeiBo/types";
import { ElMessage } from "element-plus";
import Topic from "../Topic/index.vue";
import usePrevenDefault from "../../hooks/usePrevenDefault";
import debounce from "lodash/debounce";
import "aos/dist/aos.css";
import AOS from "aos/dist/aos.js";
let centerDialogVisible = ref(false);
let isShowComment = ref<boolean>(false);
const router = useRouter();
const store = useStore();
let dialogVisible = ref<boolean>(false);
let dialogImageUrl = ref<string>("");
let userInfos = computed(() => store.state.userInfos);
let commentCount = ref<number>(0);
let showContent = ref<boolean>(true);

//显示回关
let followBack = ref<boolean>(false);
// 显示取消关注
let showUnFollow = ref<boolean>(false);
//是否已经点过赞
let isLike = ref<boolean>(false);
let likeCount = ref<number>(0);
const { $api } = getCurrentInstance()!.appContext.config.globalProperties!;
//markdown配置
const md = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        // 得到经过highlight.js之后的html代码
        const preCode = hljs.highlight(lang, str, true).value;
        // 以换行进行分割
        const lines = preCode.split(/\n/).slice(0, -1);
        // 添加自定义行号
        let html = lines
          .map((item, index) => {
            return (
              '<li><span class="line-num" data-line="' +
              (index + 1) +
              '"></span>' +
              item +
              "</li>"
            );
          })
          .join("");
        html = "<ol>" + html + "</ol>";
        // 添加代码语言
        if (lines.length) {
          html += '<b class="name">' + lang + "</b>";
        }
        return '<pre class="hljs"><code>' + html + "</code></pre>";
      } catch (__) {}
    }
    // 未添加代码语言，此处与上面同理
    const preCode = md.utils.escapeHtml(str);
    const lines = preCode.split(/\n/).slice(0, -1);
    let html: any = lines
      .map((item, index) => {
        return (
          '<li><span class="line-num" data-line="' +
          (index + 1) +
          '"></span>' +
          item +
          "</li>"
        );
      })
      .join("");
    html = "<ol>" + html + "</ol>";
    return '<pre class="hljs"><code>' + html + "</code></pre>";
  },
});
defineExpose({
  followBack,
  showUnFollow,
});
md.use(mdMark);
md.use(MarkdownItContainer, "warning", {
  validate: function (params: any) {
    return params.trim() === "warning";
  },
  render: (tokens: any, idx: any) => {
    if (tokens[idx].nesting === 1) {
      const icon = `<i class="markdown-it-vue-alert-icon markdown-it-vue-alert-icon-warning"><svg viewBox="64 64 896 896" data-icon="exclamation-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" class=""><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z"></path></svg></i>`;
      return `<div class="markdown-it-vue-alter markdown-it-vue-alter-warning">${icon}`;
    } else {
      return "</div>";
    }
  },
})
  .use(MarkdownItContainer, "info", {
    validate: function (params: any) {
      return params.trim() === "info";
    },
    render: (tokens: any, idx: any) => {
      if (tokens[idx].nesting === 1) {
        const icon = `<i class="markdown-it-vue-alert-icon markdown-it-vue-alert-icon-info"><svg viewBox="64 64 896 896" data-icon="info-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" class=""><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm32 664c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V456c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272zm-32-344a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z"></path></svg></i>`;
        return `<div class="markdown-it-vue-alter markdown-it-vue-alter-info">${icon}`;
      } else {
        return "</div>";
      }
    },
  })
  .use(MarkdownItContainer, "success", {
    validate: function (params: any) {
      return params.trim() === "success";
    },
    render: (tokens: any, idx: any) => {
      if (tokens[idx].nesting === 1) {
        const icon = `<i class="markdown-it-vue-alert-icon markdown-it-vue-alert-icon-success"><svg viewBox="64 64 896 896" data-icon="check-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" class=""><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"></path></svg></i>`;
        return `<div class="markdown-it-vue-alter markdown-it-vue-alter-success">${icon}`;
      } else {
        return "</div>";
      }
    },
  })
  .use(MarkdownItContainer, "error", {
    validate: function (params: any) {
      return params.trim() === "error";
    },
    render: (tokens: any, idx: any) => {
      if (tokens[idx].nesting === 1) {
        const icon = `<i class="markdown-it-vue-alert-icon markdown-it-vue-alert-icon-error"><svg viewBox="64 64 896 896" data-icon="close-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" class=""><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path></svg></i>`;
        return `<div class="markdown-it-vue-alter markdown-it-vue-alter-error">${icon}`;
      } else {
        return "</div>";
      }
    },
  });
const props = defineProps({
  BlogBaseInfo: {
    type: Object as PropType<WeiBoBaseType>,
  },
});
const emits = defineEmits(["getfansAndFollowing"]);
//微博内容渲染
const contentHTML = computed(() => {
  const { content } = props.BlogBaseInfo!;
  if (content) {
    return md.render(content);
  }
});
// 跳转个人主页
const goPersonal = (id: number) => {
  router.push({ name: "Personal", params: { id } });
};
//查看图片
const previewImg = (item: string) => {
  dialogImageUrl.value = item;
  dialogVisible.value = true;
};
//获取点赞数据
const getLikeData = async (blogId: number) => {
  let res = await $api.blog.reqLikeData(blogId);
  // console.log();
  if (res.code == 200) {
    likeCount.value = res.data.likeList.length;
    //判断这个博客的点赞列表中有没有当前用户(懒得写类型了，直接any)
    isLike.value = res.data.likeList.some((item: any) => {
      return userInfos.value.id == item.userId;
    });
  }
};
// 关注
const followUser = debounce(async (id: number) => {
  let res = await $api.user.reqFollowUser(id);
  // console.log(res);
  if (res.code == 200) {
    ElMessage.success("关注成功");
    showUnFollow.value = true;
    emits("getfansAndFollowing");
  }
}, 500);
//取消关注
const unFollowing = debounce(async (id: number) => {
  let res = await $api.user.reqUnFollowUser(id);
  // console.log(res);
  if (res.code == 200) {
    ElMessage.success("取消关注成功！");
    emits("getfansAndFollowing");
  }
}, 500);
//删除博客
const deleteBlog = async (id: number) => {
  let res = await $api.blog.reqDeleteBlog(id);
  if (res.code == 200) {
    ElMessage.success("删除成功!");
    centerDialogVisible.value = false;
    showContent.value = false;
  }
};
//获取评论数量
const getCommentCount = (count: number) => {
  commentCount.value = count;
};
//点赞或者取消点赞博客
const likeOrUnLikeBlog = debounce(async (blogId: number) => {
  // console.log(blogId);
  if (!store.state.isLogin) {
    ElMessage.error("请先登录！");
    return;
  }
  if (isLike.value) {
    //取消点赞
    isLike.value = false;
    likeCount.value -= 1;
    let res = await $api.user.reqUnLikeBlog(blogId);
    // console.log("取消点赞结果", res);
  } else {
    isLike.value = true;
    likeCount.value += 1;
    let res = await $api.user.reqLikeBlog(blogId);
    // console.log("点赞结果", res);
  }
}, 500);
provide("authorId", props.BlogBaseInfo?.user?.id);
usePrevenDefault("aitem");
onMounted(() => {
  AOS.init({
    offset: 200,
    duration: 300,
    easing: "ease-in-sine",
    delay: 100,
  });
  getLikeData(props.BlogBaseInfo?.id!);
});
watch(
  () => store.state.fansData,
  async (val) => {
    followBack.value = val!.userList?.some((user: UserData, index: number) => {
      return user.id == props.BlogBaseInfo?.user?.id;
    })!;
  },
  { immediate: true }
);
watch(
  () => store.state.followingData,
  (val: followListType) => {
    showUnFollow.value = val.userList?.some((user, index: number) => {
      return user.user?.id == props.BlogBaseInfo?.user?.id;
    })!;
    if (showUnFollow.value) {
      followBack.value = false;
    }
  },
  { immediate: true }
);
</script>
<style lang="less" scoped>
@import "./index.css";
.content {
  max-height: 700px;
  overflow: auto !important;
  margin-bottom: 10px;
  .skeleton {
    .avatar {
      display: flex;
    }
  }
  border-radius: 10px;
  overflow: hidden;
  .loadedContent {
    background-color: #fff;
    border-radius: 10px;
    .userinfo {
      display: flex;
      padding: 20px;
      .useravatar {
        width: 60px;
        height: 60px;
        cursor: pointer;
        &:hover {
          filter: brightness(90%);
        }
        img {
          width: 100%;
          height: 100%;
          border-radius: 100%;
          object-fit: cover;
        }
      }
      .right {
        display: flex;
        flex-direction: column;
        justify-content: center;
        margin-left: 10px;

        .nickName {
          font-size: 16px;
          font-weight: 700;
        }
        .createTime {
          font-size: 12px;
          color: #939393;
          margin-top: 5px;
        }
      }
      .btnContainer {
        flex: 1;
        display: flex;
        justify-content: flex-end;
        .followBtnBox,
        .deleteBlogBox {
          display: flex;
          align-items: center;
          justify-content: flex-end;
          .btn,
          .unbtn {
            background-color: #ff8200;
            padding: 8px 10px;
            width: 70px;
            font-size: 14px;
            border-radius: 20px;
            color: #fff;
            display: flex;
            justify-content: center;
            align-items: center;
            .iconfont {
              color: #fff;
              font-size: 12px;
              margin-right: 5px;
            }
            &:hover {
              cursor: pointer;
              background-color: #ff5900;
            }
          }
          .unbtn {
            background-color: #ccc;
            width: 80px;
            &:hover {
              cursor: pointer;
              background-color: #939393;
            }
          }
        }
      }
      .deleteBlogBox {
        margin-left: 5px;
        .iconfont {
          font-size: 18px;
          color: #ff8200;
          &:hover {
            cursor: pointer;
            transform: scale(1.2);
          }
        }
      }
    }
    .weiboContent {
      margin: 0 20px 20px 80px;
      word-wrap: break-word;
      white-space: pre-wrap;
      font-size: 14px;
      :deep(.hljs) {
        padding: 8px 2px;
        border-radius: 5px;
        position: relative;
        background-color: #282c34;
        ol {
          list-style: decimal;
          margin: 0;
          margin-left: 40px;
          padding: 0;
          padding: 20px !important;
          li {
            // list-style: decimal-leading-zero;
            position: relative;
            padding-left: 10px;
            .line-num {
              position: absolute;
              left: -40px;
              top: 0;
              width: 40px;
              height: 100%;
              border-right: 1px solid rgba(252, 252, 252, 0.915);
            }
          }
        }
        b.name {
          position: absolute;
          top: 2px;
          right: 12px;
          z-index: 10;
          color: #999;
          pointer-events: none;
        }
      }
      :deep(.aitem) {
        color: #ff8200;
      }
    }
    .weiboIMGList {
      width: 100%;
      display: flex;
      flex-wrap: wrap;
      padding: 0 240px 20px 170px;
      .imageItem {
        width: 140px;
        height: 140px;
        margin-right: 5px;
        margin-bottom: 5px;
        img {
          border-radius: 5px;
          height: 100%;
          width: 100%;
          object-fit: cover;
          border: 1px solid #f4f4f4;
          cursor: zoom-in;
          &:hover {
            filter: brightness(70%);
          }
        }
      }
    }
    .tools {
      width: 100%;
      display: flex;
      justify-content: space-around;
      padding: 10px 20px 20px 20px;
      color: #939393;
      font-size: 14px;

      // border-top: 1px solid #f2f2f2;
      .zan,
      .pinglun {
        &:hover {
          color: #ff8200;
          cursor: pointer;
        }
      }
    }
  }
}
:deep(.el-dialog__body) {
  display: flex;
  justify-content: center;
  .text {
    color: #e33438;
  }
}
.like {
  color: #ff8200;
}
.el-dialog {
  .el-dialog__body {
    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  }
}
</style>
